import json
import asyncio
import websockets
import tkinter as tk
from tkinter import font
from tkinter import StringVar
import threading

class SwipeBanner(tk.Frame):
    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)
        self.master = master
        self.current_page = 0
        self.pages = []
        # 存储所有标签对象
        self.vartext = {
            "finance_info": {},
            "finance_comment_info": {},
            "host_info": {},
            "hot_search_info": {}
        }

    def add_page(self, page_widget):
        """添加一个新的页面，页面是一个tkinter控件"""
        self.pages.append(page_widget)
        page_widget.place(x=self.current_page * self.winfo_width(), y=0, relwidth=1, relheight=1)
        # 绑定鼠标点击事件
        page_widget.bind("<Button-1>", self.on_click)

    def show(self):
        """展示所有页面"""
        self.pack(fill="both", expand=True)
        self.update_pages_position()

    def update_pages_position(self):
        """更新页面的位置"""
        for idx, page in enumerate(self.pages):
            # 计算每个页面的 x 位置
            x_pos = (idx - self.current_page) * self.winfo_width()

            # 如果页面是当前页面，显示它；否则，隐藏它
            if idx == self.current_page:
                page.place(x=x_pos, y=0, relwidth=1, relheight=1)
            else:
                page.place_forget()  # 隐藏其他页面

    def first_page(self):
        """切换到下一个页面"""
        self.update_pages_position()

    def next_page(self):
        """切换到下一个页面"""
        self.current_page = (self.current_page + 1) % len(self.pages)
        self.update_pages_position()

    def previous_page(self):
        """切换到上一页"""
        self.current_page = (self.current_page - 1) % len(self.pages)
        self.update_pages_position()

    def on_click(self, event):
        """根据点击的 x 坐标切换页面"""
        # 计算点击位置所在的列
        num_columns = 10
        column_width = self.winfo_width() / num_columns

        # 点击第一列 (第 1 列是第 0 列，点击坐标在 [0, column_width] 范围内)
        if event.x < column_width:
            self.previous_page()  # 点击第 1 列切换到上一页
        # 点击最后一列 (第 10 列是第 9 列，点击坐标在 [9 * column_width, 10 * column_width] 范围内)
        elif event.x >= self.winfo_width() - column_width:
            self.next_page()  # 点击第 10 列切换到下一页

    def create_base_control(self):
        title_font = font.Font(size=12, weight="bold")
        parent = self.pages[0]
        self.column_width = parent.winfo_screenwidth() // 4
        parent.grid_columnconfigure(0, weight=1, minsize=self.column_width)
        parent.grid_columnconfigure(1, weight=1, minsize=self.column_width)
        parent.grid_columnconfigure(2, weight=1, minsize=self.column_width)
        parent.grid_columnconfigure(3, weight=1, minsize=self.column_width)
        parent.grid_rowconfigure(0, weight=1)

        # 左侧显示金融信息
        self.frame_left = tk.Frame(parent)
        self.frame_left.grid(row=0, column=0, padx=5, pady=5, sticky="nswe")
        financial_label = tk.Label(self.frame_left, text="远程信息", font=title_font, bg="cyan", fg="black", anchor="w")
        financial_label.pack(fill=tk.X, pady=5)
        # 右侧显示其他信息
        self.frame_right2 = tk.Frame(parent)
        self.frame_right2.grid(row=0, column=1, padx=5, pady=5, sticky="nswe")
        financial_label = tk.Label(self.frame_right2, text="评论信息", font=title_font, bg="cyan", fg="black", anchor="w")
        financial_label.pack(fill=tk.X, pady=5)
        # 左侧显示主机资源
        self.frame_left2 = tk.Frame(parent)
        self.frame_left2.grid(row=0, column=2, padx=5, pady=5, sticky="nswe")
        financial_label = tk.Label(self.frame_left2, text="主机资源", font=title_font, bg="cyan", fg="black", anchor="w")
        financial_label.pack(fill=tk.X, pady=5)
        # 右侧显示热搜信息
        self.frame_right = tk.Frame(parent)
        self.frame_right.grid(row=0, column=3, padx=5, pady=5, sticky="nswe")
        financial_label = tk.Label(self.frame_right, text="实时热搜", font=title_font, bg="cyan", fg="black", anchor="w")
        financial_label.pack(fill=tk.X, pady=5)


    def show_control(self):
        label_font = font.Font(size=12)
        for item, data in self.finance_info.items():
            for key, price in data.items():
                data_text = f"{key}|{price['latest_price']}|{price['price_percent']}"
                if (item, key) not in self.vartext["finance_info"]:
                    var_text = StringVar()
                    var_text.set(data_text)
                    label = tk.Label(self.frame_left, textvariable=var_text, font=label_font, fg="black", anchor="w", wraplength=self.column_width)
                    label.pack(fill=tk.X, pady=5)
                    self.vartext["finance_info"][(item, key)] = var_text
                else:
                    self.vartext["finance_info"][(item, key)].set(data_text)
                    pass

        for item, data in self.finance_comment_info.items():
            for key, comments in data.items():
                for comment in comments:
                    data_text = f"{key}|{comment['user']}|{comment['province']}{comment['city']}|{comment['comment']}"
                    if (item, key, comment['user']) not in self.vartext["finance_comment_info"]:
                        var_text = StringVar()
                        var_text.set(data_text)
                        label = tk.Label(self.frame_right2, textvariable=var_text, font=label_font, fg="black", anchor="w", wraplength=self.column_width)
                        label.pack(fill=tk.X, pady=5)
                        self.vartext["finance_comment_info"][(item, key, comment['user'])] = var_text
                    else:
                        # 更新已存在标签内容
                        self.vartext["finance_comment_info"][(item, key, comment['user'])].set(data_text)
                        pass

        for item, data in self.host_info.items():
            data_text = f"{item}|{data}"
            if item not in self.vartext["host_info"]:
                var_text = StringVar()
                var_text.set(data_text)
                label = tk.Label(self.frame_left2, textvariable=var_text, font=label_font, fg="black", anchor="w", wraplength=self.column_width)
                label.pack(fill=tk.X, pady=5)
                self.vartext["host_info"][item] = var_text
            else:
                # 更新已存在标签内容
                self.vartext["host_info"][item].set(data_text)
                pass

        for item, data in self.hot_searche_info.items():
            for search in data:
                data_text = item + "|" + search
                if (item, search) not in self.vartext["hot_search_info"]:
                    var_text = StringVar()
                    var_text.set(data_text)
                    label = tk.Label(self.frame_right, textvariable=var_text, font=label_font, fg="black", anchor="w", wraplength=self.column_width)
                    label.pack(fill=tk.X, pady=5)
                    self.vartext["hot_search_info"][(item, search)] = var_text
                else:
                    # 更新已存在标签内容
                    self.vartext["hot_search_info"][(item, search)].set(data_text)
                    pass

    def set_request_info(self, uri):
        self.uri = uri

    async def fetch_data(self):
        while True:
            try:
                async with websockets.connect(self.uri) as websocket:
                    while True:
                        # 发送请求ws://localhost:30027/ws
                        # request_data = {"path": "/greatInfo"}
                        # await websocket.send(json.dumps(request_data))
                        await websocket.send("{\"path\": \"/greatInfo\"}")

                        # 接收响应
                        response = await websocket.recv()
                        response_data = json.loads(response)

                        # 提取数据
                        self.host_info = response_data["data"]["host_info"]
                        self.finance_info = response_data["data"]["finance_info"]
                        self.finance_comment_info = response_data["data"]["finance_comment_info"]
                        self.hot_searche_info = response_data["data"]["hot_searche_info"]

                        # 更新UI
                        self.show_control()
                        await asyncio.sleep(1)
            except Exception as e:
                print(f"WebSocket error: {e}")

            await asyncio.sleep(3)

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("800x600")
    banner = SwipeBanner(root)
    page1 = tk.Frame(banner)
    banner.add_page(page1)
    banner.show()
    banner.set_request_info("ws://192.168.10.112:30027/ws")
    banner.create_base_control()

    # 启动异步任务获取数据
    def start_websocket_task():
        loop = asyncio.new_event_loop()  # 创建新的事件循环
        asyncio.set_event_loop(loop)
        loop.run_until_complete(banner.fetch_data())  # 运行 WebSocket 获取数据
    thread = threading.Thread(target=start_websocket_task, daemon=True)
    thread.start()

    def close_window(event):
        event.widget.destroy()

    def toggle_fullscreen(event):
        state = root.attributes('-fullscreen')
        root.attributes('-fullscreen', not state)

    root.bind("<Escape>", close_window)
    root.bind("<F11>", toggle_fullscreen)
    root.mainloop()
